﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;

/// <summary>
/// Summary description for UserManager
/// </summary>
public class UserManager
{
    SerializableDictionary<string, User> users = null;
    SerializableDictionary<string, SerializableDictionary<string, DateTime>> userRefs = null;
    DataManager usersDataMan = new DataManager("users.xml", typeof(SerializableDictionary<string, User>));
    DataManager userRefsDataMan = new DataManager("userRefs.xml", typeof(SerializableDictionary<string, SerializableDictionary<string, DateTime>>));

    private static UserManager _instance = null;
	private UserManager()
	{
        this.users = this.usersDataMan.LoadData() as SerializableDictionary<string, User>;
        if (users == null)
        {
            this.users = new SerializableDictionary<string, User>();
        }

        this.userRefs = this.userRefsDataMan.LoadData() as SerializableDictionary<string, SerializableDictionary<string, DateTime>>;
        if (userRefs == null)
        {
            this.userRefs = new SerializableDictionary<string, SerializableDictionary<string, DateTime>>();
        }
	}

    static public UserManager GetInstance()
    {
        if(_instance == null)
        {
            _instance = new UserManager();
        }
        return _instance;
    }

    public void AddUser(User user)
    {
        if (!this.users.ContainsKey(user.UserName))
        {
            this.users.Add(user.UserName, user);
        }
        this.usersDataMan.SaveData(this.users);
    }

    public bool IsUserExist(string email)
    {
        return this.users.ContainsKey(email);
    }

    public void Save()
    {
        this.usersDataMan.SaveData(this.users);
    }

    public User FindUser(string email)
    {
        if (this.users.ContainsKey(email))
        {
            User user = this.users[email];
            return user;
        }
        return null;
    }

    public string GenerateRandomCode()
    {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 6; i++)
        {
            int seed = DateTime.Now.Year + DateTime.Now.Minute + DateTime.Now.Second + i 
                + DateTime.Now.Millisecond + DateTime.Now.Month + DateTime.Now.Day + DateTime.Now.Hour;
            Random r = new Random(seed);
            int lr = r.Next(0, 2);
            char c;
            if (lr == 0)
            {
                c = (char)('a' + r.Next(0, 26));
            }
            else
            {
                c = (char)('0' + r.Next(0, 9));
            }
            sb.Append(c);
        }

        return sb.ToString();
    }

    public void UpdateUserRef(UserRef userRef)
    {
        if (!this.userRefs.ContainsKey(userRef.UserName))
        {
            SerializableDictionary<string, DateTime> refList = new SerializableDictionary<string, DateTime>();
            refList[userRef.Ip] = userRef.Time;
            this.userRefs[userRef.UserName] = refList;
        }
        else
        {
            SerializableDictionary<string, DateTime> refList = userRefs[userRef.UserName];
            if (refList.ContainsKey(userRef.Ip))
            {
                refList.Remove(userRef.Ip);
            }
            refList.Add(userRef.Ip, userRef.Time);
        }
        this.userRefsDataMan.SaveData(this.userRefs);
    }

    // Return true if the user hasn't been refed from the ip within 24 hours
    public bool IsValidUserRef(UserRef userRef)
    {
        //this user has never been refed
        if (!this.userRefs.ContainsKey(userRef.UserName))
        {
            return true;
        }

        //this user has never been refed from this ip
        SerializableDictionary<string, DateTime> refList = userRefs[userRef.UserName];
        if (!refList.ContainsKey(userRef.Ip))
        {
            return true;
        }

        DateTime lastRefTime = refList[userRef.Ip];
        if (DateTime.Now - lastRefTime >= TimeSpan.FromHours(24))
        {
            return true;
        }

        return false;
    }

}